<template>
  <div class="login-box">
    <canvas ref="particle-canvas" id="particle-canvas"></canvas>
    <div class="login-box-bg absolute x-y-center">
      <div class="text item">
        <el-form
          status-icon
          :rules="rules"
          ref="loginForm"
          label-width="70px"
          :model="loginForm"
          label-position="left"
        >
          <div class="align-center white login-title">系统登录</div>
          <el-form-item
            label="账号"
            prop="account"
            class="mt20"
            :label-width="labelWidth"
          >
            <el-input
              v-model="loginForm.account"
              placeholder="请输入账号..."
            ></el-input>
          </el-form-item>
          <el-form-item
            label="密码"
            prop="password"
            class="mt20"
            :label-width="labelWidth"
          >
            <el-input
              type="password"
              autocomplete="off"
              placeholder="请输入密码..."
              v-model="loginForm.password"
            ></el-input>
          </el-form-item>

          <el-form-item label prop class="mt20 remember-item">
            <el-checkbox class="fs16 fl gray" v-model="remember"
              >记住我</el-checkbox
            >
            <span class="fs16 fr theme pointer" @click="resetForm()">重置</span>
          </el-form-item>
          <el-form-item class="mt20 pt10 login-item">
            <el-button class="login-btn theme-btn" @click="submitForm"
              >登 录</el-button
            >
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script>
import axios from "axios";
import { mapGetters } from "vuex";
import { login } from "@/apis/user";
import setting from "@/../config/setting";
import { vlength } from "@/utils/verification.js";

export default {
  name: "Login",
  data() {
    return {
      loginForm: {
        account: "",
        password: ""
      },
      canvas: {},
      remember: false,
      labelWidth: "95px",
      rules: {
        account: {
          validator: vlength(5, 12, "请输入账号"),
          trigger: "blur"
        },
        password: {
          validator: vlength(5, 12, "请输入密码"),
          trigger: "blur"
        }
      }
    };
  },
  created() {
    this.loginForm.account = JSON.parse(localStorage.getItem("loginForm"))
      ? JSON.parse(localStorage.getItem("loginForm")).account
      : "";
    this.loginForm.password = JSON.parse(localStorage.getItem("loginForm"))
      ? JSON.parse(localStorage.getItem("loginForm")).password
      : "";
    this.remember = localStorage.getItem("remember")
      ? Boolean(localStorage.getItem("remember"))
      : false;
  },
  mounted() {
    this.canvasBg(this.$refs["particle-canvas"]);
  },
  methods: {
    canvasBg(_canvas) {
      // modified version of random-normal
      const normalPool = o => {
        var r = 0;
        do {
          var a = Math.round(normal({ mean: o.mean, dev: o.dev }));
          if (a < o.pool.length && a >= 0) return o.pool[a];
          r++;
        } while (r < 100);
      };
      const randomNormal = o => {
        if (
          ((o = Object.assign({ mean: 0, dev: 1, pool: [] }, o)),
          Array.isArray(o.pool) && o.pool.length > 0)
        )
          return normalPool(o);
        var r,
          a,
          n,
          e,
          l = o.mean,
          t = o.dev;
        do {
          r = (a = 2 * Math.random() - 1) * a + (n = 2 * Math.random() - 1) * n;
        } while (r >= 1);
        return (e = a * Math.sqrt((-2 * Math.log(r)) / r)), t * e + l;
      };

      const NUM_PARTICLES = 600;
      const PARTICLE_SIZE = 0.5; // View heights
      const SPEED = 80000; // Milliseconds

      let particles = [];

      const rand = (low, high) => {
        return Math.random() * (high - low) + low;
      };

      const createParticle = canvas => {
        const colour = {
          r: 36,
          g: randomNormal({ mean: 125, dev: 20 }),
          b: 162,
          a: rand(0, 1)
        };
        return {
          x: -2,
          y: -2,
          diameter: Math.max(
            0,
            randomNormal({ mean: PARTICLE_SIZE, dev: PARTICLE_SIZE / 2 })
          ),
          duration: randomNormal({ mean: SPEED, dev: SPEED * 0.1 }),
          amplitude: randomNormal({ mean: 16, dev: 2 }),
          offsetY: randomNormal({ mean: 0, dev: 10 }),
          arc: Math.PI * 2,
          startTime: performance.now() - rand(0, SPEED),
          colour: `rgba(${colour.r}, ${colour.g}, ${colour.b}, ${colour.a})`
        };
      };

      const moveParticle = (particle, canvas, time) => {
        const progress =
          ((time - particle.startTime) % particle.duration) / particle.duration;
        return {
          ...particle,
          x: progress,
          y:
            Math.sin(progress * particle.arc) * particle.amplitude +
            particle.offsetY
        };
      };

      const drawParticle = (particle, canvas, ctx) => {
        this.canvas = _canvas;
        const vh = this.canvas.height / 100;

        ctx.fillStyle = particle.colour;
        ctx.beginPath();
        ctx.ellipse(
          particle.x * this.canvas.width,
          particle.y * vh + this.canvas.height / 2,
          particle.diameter * vh,
          particle.diameter * vh,
          0,
          0,
          2 * Math.PI
        );
        ctx.fill();
      };

      const draw = (time, canvas, ctx) => {
        // Move particles
        particles.forEach((particle, index) => {
          particles[index] = moveParticle(particle, canvas, time);
        });

        // Clear the canvas
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // Draw the particles
        particles.forEach(particle => {
          drawParticle(particle, canvas, ctx);
        });

        // Schedule next frame
        requestAnimationFrame(time => draw(time, canvas, ctx));
      };

      const initializeCanvas = () => {
        this.canvas = _canvas;

        this.canvas.width = this.canvas.offsetWidth * window.devicePixelRatio;
        this.canvas.height = this.canvas.offsetHeight * window.devicePixelRatio;
        let ctx = this.canvas.getContext("2d");
        window.addEventListener("resize", () => {
          this.canvas.width = this.canvas.offsetWidth * window.devicePixelRatio;
          this.canvas.height =
            this.canvas.offsetHeight * window.devicePixelRatio;
          ctx = this.canvas.getContext("2d");
        });

        return [this.canvas, ctx];
      };

      const startAnimation = () => {
        const [canvas, ctx] = initializeCanvas();

        for (let i = 0; i < NUM_PARTICLES; i++) {
          particles.push(createParticle(canvas));
        }

        requestAnimationFrame(time => draw(time, canvas, ctx));
      };
      startAnimation();
    },
    async submitForm() {
      this.$refs["loginForm"].validate(valid => {
        if (valid) {
          if (this.remember) {
            if (this.loginForm.account && this.loginForm.password) {
              const form = {
                account: this.loginForm.account,
                password: this.loginForm.password
              };
              localStorage.setItem("remember", true);
              localStorage.setItem("loginForm", JSON.stringify(form));
            }
          } else {
            localStorage.clear();
          }
          let params = {
            userName: this.loginForm.account,
            password: this.loginForm.password
          };

          login(params)
            .then(data => {
              if (data) {
                this.$message({
                  type: "success",
                  message: data.msg
                });
                sessionStorage.setItem("Token", data.object.token);
                sessionStorage.setItem("userId", data.object.userId);
                this.$router.push({ name: "layout" });
              }
            })
            .catch(error => {
              console.log(error);
            });
        }
      });
    },
    resetForm() {
      this.loginForm = {
        account: "",
        password: ""
      };
      this.$message({ message: "已重置！", duration: 1000 });
    }
  }
};
</script>

<style scoped lang="less"></style>
